package com.gaofans.nrpc.common.context;

import com.gaofans.nrpc.common.processor.Builder;
import com.gaofans.nrpc.common.protocol.RpcRequest;
import io.netty.util.concurrent.EventExecutor;

import java.io.Serializable;
import java.util.Map;
import java.util.Objects;

/**
 * @author GaoFans
 */
public class ContextRequest extends RpcRequest implements Context {

    private EventExecutor executor;


    private final RpcRequest request;

    public static class ContextRequestBuilder implements Builder<ContextRequest>{

        private final ContextRequest contextRequest;

        public ContextRequestBuilder(RpcRequest request) {
            this.contextRequest = new ContextRequest(Objects.requireNonNull(request));
        }

        public ContextRequestBuilder executor(EventExecutor executor){
            contextRequest.executor = executor;
            return this;
        }

        public ContextRequestBuilder executor(SelectableExecutor chooser){
            contextRequest.executor = chooser.select(contextRequest.request.getSequenceId());
            return this;
        }

        @Override
        public ContextRequest build() {
            Objects.requireNonNull(contextRequest.executor);
            return contextRequest;
        }
    }

    private ContextRequest(RpcRequest request) {
        this.request = request;
    }

    @Override
    public EventExecutor executor() {
        return executor;
    }

    public RpcRequest getRequest() {
        return request;
    }

    @Override
    public long getSequenceId() {
        return request.getSequenceId();
    }

    @Override
    public void setSequenceId(long sequenceId) {
        request.setSequenceId(sequenceId);
    }

    @Override
    public void putHeader(String key, Serializable value) {
        request.putHeader(key, value);
    }

    @Override
    public Serializable header(String key) {
        return request.header(key);
    }

    @Override
    public String getClassName() {
        return request.getClassName();
    }

    @Override
    public void setClassName(String className) {
        request.setClassName(className);
    }

    @Override
    public String getMethodName() {
        return request.getMethodName();
    }

    @Override
    public void setMethodName(String methodName) {
        request.setMethodName(methodName);
    }

    @Override
    public Class<?>[] getTypeParameters() {
        return request.getTypeParameters();
    }

    @Override
    public void setTypeParameters(Class<?>[] typeParameters) {
        request.setTypeParameters(typeParameters);
    }

    @Override
    public Object[] getParametersVal() {
        return request.getParametersVal();
    }

    @Override
    public void setParametersVal(Object[] parametersVal) {
        request.setParametersVal(parametersVal);
    }

    @Override
    public byte getType() {
        return request.getType();
    }

    @Override
    public Serializable removeHeader(String key) {
        return request.removeHeader(key);
    }

    @Override
    public Map<String, Serializable> headers() {
        return request.headers();
    }
}
